# 此文件为服务器的运行主逻辑文件，也是程序启动的入口
# websockets用到async await的异步编程模式
import asyncio
import websockets
# 这是接收上位机控制命令的处理函数
from operate import handler
# 这是设置全局状态变量的接口，用于控制当前是否有正在运行的程序
from utils import set_global_value

# 检测客户端权限，用户名密码通过才能退出循环，不重要
async def check_permit(websocket):
  while True:
    recv_str = await websocket.recv()
    cred_dict = recv_str.split(":")
    if cred_dict[0] == "admin" and cred_dict[1] == "123456":
        response_str = "congratulation, you have connect with server\r\nnow, you can do something else"
        await websocket.send(response_str)

        
        print('认证成功')
        return True
    else:
        response_str = "sorry, the username or password is wrong, please submit again"
        await websocket.send(response_str)
        print('认证失败')

# 接收客户端消息并处理，在这里进行控制命令的判断和处理
async def recv_msg(websocket):
    while True:
        print('等待指令')
        recv_text = await websocket.recv()

        # 控制命令解析及执行
        handler(recv_text, websocket)

# 服务器端主逻辑
# websocket和path是该函数被回调时自动传过来的，不需要自己传
async def main_logic(websocket, path):
    await check_permit(websocket)

    # 这里进行socket连接的相关异常处理
    try:
        await recv_msg(websocket)
    # 这个异常时客户端连接中断的异常，一般就是客户端关闭时触发
    except websockets.exceptions.ConnectionClosedOK:
        print('客户端断开连接')
        # 清空运行标记
        set_global_value('status', False)


# 这是程序运行的主逻辑

# 把ip换成自己本地的ip
start_server = websockets.serve(main_logic, "127.0.0.1", 3000)
# 如果要给被回调的main_logic传递自定义参数，可使用以下形式
# 一、修改回调形式
# import functools
# start_server = websockets.serve(functools.partial(main_logic, other_param="test_value"), '10.10.6.91', 5678)
# 修改被回调函数定义，增加相应参数
# async def main_logic(websocket, path, other_param)

print('等待客户端连接')
asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()